using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class PlayerController : MonoBehaviour
{
    public int runSpeed;
    public int jumpSpeed;
    public int health;

    private float xInput;
    private bool isGround;
    private Animator _animator;
    private Rigidbody2D rigidbody2D;
    private BoxCollider2D boxCollider2D;

    [Header("冲刺相关参数")]
    public float dashCD;            //冲刺的cd
    public float dashSpeed;         //冲刺速度
    public float dashTime;
    private bool canDash;
    private float dashTimeLeft;     //还剩下多长时间可以冲刺
    private float dashStartTime = -10;    //冲刺时的系统时间

    [Header("轻攻击相关参数")] 
    public bool isAttack;       //锁定攻击（攻击动画播放时，再按攻击键不会重新播放攻击动画）
    public float interval;      //允许连击的时间
    public float attackSpeed;   //攻击时向前移动的速度
    public int damage;
    private int combo;          //攻击段数
    private float timer;

    [Header("打击感相关")] 
    public float shakeDuration;  //相机震动时间
    public float strength;  //震动幅度
    public float pauseDuration; //帧暂停时间
    public float tileScale; //缩放时间

    private FSM enemyFsm;
    public static bool attacked;
    
    
    // Start is called before the first frame update
    void Start()
    {
        rigidbody2D = gameObject.GetComponent<Rigidbody2D>();
        boxCollider2D = gameObject.GetComponent<BoxCollider2D>();
        _animator = gameObject.GetComponent<Animator>();
        HealthBar.totalHealth = HealthBar.curHealth = this.health;

    }

    // Update is called once per frame
    void Update()
    {
        CheckGround();
        Jump();
        ReadyToRun();
        IsDash();
        Attack();
        ChangeAnim();
        SkillUi.instance.ChangeCd(dashCD);           //进入图标cd时间
    }

    void FixedUpdate()
    {
        Run();
        Dash();

    }

    private void CheckGround()
    {
        isGround = boxCollider2D.IsTouchingLayers(LayerMask.GetMask("Ground"));
    }

    private void ChangeAnim()
    {
        _animator.SetBool("Jump", !isGround);
        _animator.SetBool("Run", xInput != 0.0f && isGround);
    }

    private void Jump()
    {
        if (Input.GetButtonDown("Jump") && isGround)
        {
            rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, jumpSpeed);
        }
    }

    private void ReadyToRun()
    {
        xInput = Input.GetAxisRaw("Horizontal");    //GetAxisRaw只返回[-1,0,1]
        if (xInput != 0)
        {
            transform.localScale = new Vector3(xInput, 1, 1);
        }
        
    }

    private void Run()
    {
        if (xInput != 0.0f && !isAttack)
        {
            rigidbody2D.velocity = new Vector2(xInput * runSpeed, rigidbody2D.velocity.y);
        }
        
        if (isAttack && isGround)
        {
            // 存储目标水平速度值
            float targetVelocityX = transform.localScale.x * attackSpeed;
            // 使用 DOTween 渐变修改水平速度（保持垂直速度不变）
            DOTween.To(
                getter: () => rigidbody2D.velocity.x,    // 获取当前水平速度
                setter: x => rigidbody2D.velocity = new Vector2(x, rigidbody2D.velocity.y), // 设置新速度
                endValue: targetVelocityX,               // 目标水平速度
                duration: 0.2f                           // 渐变时间（按需调整）
            ).SetUpdate(UpdateType.Fixed);         // 同步物理更新
            // rigidbody2D.velocity = new Vector2(transform.localScale.x* attackSpeed, rigidbody2D.velocity.y);
        }
    }

    private void Dash()
    {
        if (canDash)
        {
            if (dashTimeLeft>0) //还在冲刺中
            {
                rigidbody2D.velocity = new Vector2(xInput*dashSpeed, 0);
                dashTimeLeft -= Time.deltaTime;
                //取对象池中的残影
                ShadowPool.instance.DePool();
            }
            else
            {
                rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
                canDash = false;
            }
        }
    }

    private void IsDash()
    {
        if (Input.GetKeyDown(KeyCode.J) && xInput!=0)
        {
            if (Time.time >= (dashStartTime + dashCD)) //cd好了，可以冲刺
            {
                canDash = true;
                dashStartTime = Time.time;
                dashTimeLeft = dashTime;
                SkillUi.instance.RecoverCd();//冲刺图标进入cd
            }
        }
    }

    private void Attack()
    {
        //isAttack 锁定攻击（攻击动画播放时，再按攻击键不会重新播放攻击动画）
        if (Input.GetKeyDown(KeyCode.K) && !isAttack)
        {
            isAttack = true;
            combo += 1;
            if (combo>3)
                combo = 1;  
            //?为什么0不行。答：如果是0，在第三次攻击后，再次按k，进入if语句，这是isAttack为true，
            //但是因为combo为0，没有触发攻击动画，所以isAttack一直为ture，再按k就进不到这个语句中，就不会攻击了
            timer = interval;
            _animator.SetTrigger("LightAttack");
            _animator.SetInteger("Combo", combo);

        }

        if (timer != 0)
        {
            timer -= Time.deltaTime;
            if (timer<=0)
            {
                combo = 0;
                timer = 0;
            }
        }
    }

    public void Attacked(int damage)
    {
        _animator.SetTrigger("Attacked");
        health -= damage;
        if (health<=0)
        {
            Destroy(this.gameObject);
        }
        HealthBar.curHealth = health;
        isAttack = false;   //受伤时要将isAttack设置为false（修复bug：攻击时受伤，没有调用攻击结束关键帧，isAttack一直为true，就一直有攻击向前速度）
    }

    //关键帧调用
    private void AttackOver()
    {
        isAttack = false;
    }

    //此处设置了player的子物体可以和enemy碰撞，所以武器攻击的OnTriggerEnter2D可以写在player脚本中
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Enemy"))
        {
            
            // int tempDamage = combo == 3 ? damage * 2 : damage;              //设置第三下暴击
            // col.GetComponent<Enemy>().Hit(transform.localScale.x, tempDamage, combo);  //调用怪物受击相关代码
            // CameraController.instance.StartShake(shakeDuration, strength);       //屏幕震动
            // if (combo == 3)
            // {
            //     CameraController.instance.StartPause(pauseDuration,tileScale);   //钝帧
            // }
            
            FSM manager = other.GetComponent<FSM>();
            int tempDamage;
            if (combo == 3)
            {
                tempDamage = damage * 2;        //设置暴击伤害
                manager.parameter.critical = 2;//设置暴击率
            }
            else
            {
                tempDamage = damage;
                manager.parameter.critical = 1;
            }
            
            manager.parameter.isHit = true;
            manager.parameter.hitDamage = tempDamage;
            CameraController.instance.StartShake(shakeDuration, strength);       //屏幕震动
            if (combo == 3)
            {
                CameraController.instance.StartPause(pauseDuration,tileScale);   //钝帧
            }
        }
    }

    
}
